package com.huiyi.quickproj.jundui;

/**
 * describe: 转换程序主程序
 *
 * @author: robin
 * @email:  cuizhou6463@126.com
 * @date 2023-12-03
 */
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huiyi.quickproj.jundui.po.ResolveFileDef;
import com.huiyi.quickproj.jundui.utils.AutoDetectDelimiter;
import com.huiyi.quickproj.jundui.utils.MyUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.*;

public class DynamicCsvToSqlConverter4VoteCase {

    public static Map<String, String> parameterMaps = new HashMap<>();

    public static Map<String, ResolveFileDef> preconfMap = new HashMap<>();

    public static Map<String, List<Integer>> dbtabMap = new HashMap<>();

    public static String syslog = null;

    public static void main(String[] args) throws IOException {

        String workpath = null; // "D:\\project\\ieducation_training\\外部项目\\jundui_csv2sql";
        String preconf  = null;
        String preconfFileName = null;
        String outputpath = null;
        String mode     = null;
        String logPath  = null;
        String dbname   = null;
        String owType  = null;
        String sepstr  = null;
        String sepcount  = null;
        String headcountmakeupcount = null;
        String head  = null;
        String spetableName = null;
        String spetableNameDDl = null;
        String tableNameWay = null;
        String converType = null;


        BufferedWriter logWriter = null;
        try{
            /**
             * args = new String[] {"--workpath", "/path/", "--preconf", "/path/filename", "--mode", "pre"}; // pre, ddl, convert
             */
            args = new String[] {"--workpath", "E:\\5\\USVoterData_BF\\data\\Wyoming",
                    "--outputpath", "E:\\output\\5\\USVoterData_BF\\Wyoming",
                    "--preconf", "E:\\output\\5\\USVoterData_BF\\Wyoming\\Wyoming.json",
                    "--logPath", "E:\\output\\5\\USVoterData_BF\\Wyoming\\Wyoming.log",
                    "--preconfFileName","Wyoming.json",
                    "--dbname", "USVoterData_BF",
                    // "--sepstr", ",",
                    // "--sepcount", "1",
                    "--headcountmakeupcount","1",// 由于VOTE 里面的 head文件和 data数据 长度不匹配，如 head 头部是51个 字段, data里是 52,一般这样的数据是需要被丢弃的，那如果全部都是这样的数据，就要考虑 补偿机制。
                    "--head", "1", // 1带head 0 不带
                    "--syslog", "silent", //print silent
                    "--owType", "seq", // seq,name overwrite type
                    // 默认tableName tableNameDDL 根据目录来 可以使用 可以自定义设置
                    "--spetableName","",
                    "--spetableNameDDl","",
                    "--tableNameWay","parentConcat", // plain parentConcat 当前目录加上一级目录
                    "--converType","plaintxt", // plaintxt json
                    "--mode", "ddl"}; // pre, ddl, sql
            parameterMaps = MyUtils.parse(args);

            workpath    = parameterMaps.get("workpath");
            preconf     = parameterMaps.get("preconf");
            preconfFileName     = parameterMaps.get("preconfFileName");
            outputpath  = parameterMaps.get("outputpath");
            logPath     = parameterMaps.get("logPath");
            mode        = parameterMaps.get("mode");
            dbname      = parameterMaps.get("dbname");
            owType      = parameterMaps.get("owType");
            sepstr      = parameterMaps.get("sepstr");
            sepcount    = parameterMaps.get("sepcount");
            headcountmakeupcount    = parameterMaps.get("headcountmakeupcount");
            head        = parameterMaps.get("head");
            syslog      = parameterMaps.get("syslog");
            spetableName      = parameterMaps.get("spetableName");
            spetableNameDDl   = parameterMaps.get("spetableNameDDl");
            tableNameWay   = parameterMaps.get("tableNameWay");
            converType   = parameterMaps.get("converType");

            if(StringUtils.isEmpty(workpath) || StringUtils.isEmpty(preconf) || StringUtils.isEmpty(outputpath)){
                System.out.println("workpath or preconf file is not exists or mode is empty");
                System.exit(0);
            }
            File logPathFile = new File(logPath);
            if(!logPathFile.getParentFile().exists()){
                logPathFile.getParentFile().mkdirs();
            }
            if(!logPathFile.getParentFile().exists()){
                FileUtils.forceMkdirParent(logPathFile.getParentFile());
            }
            logWriter = new BufferedWriter(new FileWriter(logPath));

            // 1   预处理把文件输出成 Map 对象, {文件路径:{ 文件名, 数据库名, 是否需要处理 }} 从而生成出一个 预配置文件
            // 1.1 手动确认 预配置文件, 修改成可操作的文件
            if("pre".equalsIgnoreCase(mode)){

                Collection<File> _files = FileUtils.listFiles(new File(workpath), null, true);

                for(File _f : _files){
                    System.out.println(_f.getParentFile().getName());
                    if( _f.isFile()
//                            && TextFileChecker.isTextFile(_f) // 在实际运行中，发现会丢弃一些文件 如UAE 和Yeman的数据，随机放弃该查询，通过后缀名来搞定
                            && !"zip".equals(MyUtils.getExt(_f.getName()))
                            && !"tar.gz".equals(MyUtils.getExt(_f.getName()))
                            && !"pdf".equals(MyUtils.getExt(_f.getName()))
                            && !"rar".equals(MyUtils.getExt(_f.getName()))
                            && !"gz".equals(MyUtils.getExt(_f.getName()))
                            && !"7z".equals(MyUtils.getExt(_f.getName()))
                            && !"xlsx".equals(MyUtils.getExt(_f.getName()))
                            && !"xlx".equals(MyUtils.getExt(_f.getName()))
                            && !"docx".equals(MyUtils.getExt(_f.getName()))
                            && !"doc".equals(MyUtils.getExt(_f.getName()))
                            && !"Read Me.txt".equals(_f.getName())
                            && (!_f.getParentFile().getName().equalsIgnoreCase("info"))
                            && (!"json".equals(MyUtils.getExt(_f.getName())) || !preconfFileName.equalsIgnoreCase(_f.getName())
                    )
                    ){

                        ResolveFileDef def = new ResolveFileDef();
                        def.setDbName(dbname);
                        def.setFileName(_f.getName());

                        String _tblname = _f.getParentFile().getName();
                        String _ptblname = _f.getParentFile().getParentFile().getName();

                        if(!StringUtils.isEmpty(spetableName)){ //
                            _tblname = spetableName;
                        }
                        if(_tblname.indexOf(" ") > 0){
                            _tblname = _tblname.replace(" ", "_");
                            if("parentConcat".equalsIgnoreCase(tableNameWay)){ //上上和上级 父目录拼接
                                _ptblname = _ptblname.replace(" ", "_");
                                _tblname  = _ptblname + "_" + _tblname;
                            }
                        }

                        if(!StringUtils.isEmpty(spetableNameDDl)){ //
                            def.setTableName4ddl(spetableNameDDl);
                        }
                        else {
                            if("parentConcat".equalsIgnoreCase(tableNameWay)){ //上上和上级 父目录拼接
                                _ptblname = _ptblname.replace(" ", "_");
                                _tblname  = _ptblname + "_" + _tblname;
                            }
                            def.setTableName4ddl(_tblname);
                        }

                        if("seq".equals(owType)){
                            if(dbtabMap.containsKey(_tblname)){
                                log(logWriter, "tablename:" + _tblname + " exists,rename new");
                                List<Integer> integers = dbtabMap.get(_tblname);
                                int newi = MyUtils.getMaxValue(dbtabMap, _tblname) + 1;
                                integers.add(newi);
                                dbtabMap.put( _tblname, integers);
                                def.setTableName(_tblname + "_" + newi);
                            }
                            else{
                                List<Integer> integers = new ArrayList<>();
                                integers.add(0);
                                dbtabMap.put(_tblname,integers);
                                def.setTableName(_tblname);
                            }
                        }


                        if("sql".equalsIgnoreCase(MyUtils.getExt(_f.getName()))){
                            def.setIsNeedResolved("0");
                        }else{
                            def.setIsNeedResolved("1");
                        }

                        String s = _f.getAbsolutePath().replace(workpath,"");
                               s = s.replace(_f.getName(),"");
                        def.setOutputFinalPath(s);

                        if("plaintxt".equalsIgnoreCase(converType)){
                            if(StringUtils.isEmpty(sepstr)){
                                String defstr = AutoDetectDelimiter.detectBestDelimiter(AutoDetectDelimiter.readSampleLines(_f.getAbsolutePath(), 100));
                                log(logWriter, defstr);
                                def.setDefstr(defstr.split("#7#")[0]);
                                def.setCount(Integer.valueOf(defstr.split("#7#")[1]));
                            }
                            else{
                                def.setDefstr(sepstr);
                                def.setCount(Integer.valueOf(sepcount));
                            }
                        }
                        else if("json".equalsIgnoreCase(converType)){
                            def.setDefstr("");
                            def.setCount(0);
                        }
                        def.setConverType(converType);

                        def.setSize(_f.length());

                        // 设置head航投数据
                        if("1".equals(head)){
                            String headStrs = MyUtils.getHeadLineWithFilePath(_f.getAbsolutePath());
                            def.setHeads(headStrs);
                        }

                        if( _f.getAbsolutePath().contains("output") ){
                        }
                        else{
                            preconfMap.put(_f.getAbsolutePath(), def);
                        }

                    }
                }
                // 使用Jackson库将Map对象转换为JSON格式
                ObjectMapper objectMapper = new ObjectMapper();
                objectMapper.writeValue(new File(preconf), preconfMap);
                System.exit(0);
            }
            // 2 预先加载预配置文件，然后根据预配置文件，读取文件的首行，创建DDL 建表语句。
            else if("ddl".equalsIgnoreCase(mode)){
                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, LinkedHashMap> o = objectMapper.readValue(new File(preconf), Map.class);
//                System.out.println(o);
                Set<String> keys = o.keySet();
                for(Map.Entry<String, LinkedHashMap> entry : o.entrySet()){
                    LinkedHashMap<String,Object> defs = entry.getValue();

                    // System.out.println(entry.getValue());
                    ResolveFileDef resolveFileDef = convertMapToObject(defs,ResolveFileDef.class);
                    String tableName4ddl = resolveFileDef.getTableName4ddl();
                    String fileName = resolveFileDef.getFileName();
                    long size = resolveFileDef.getSize();
                    int colNum       = resolveFileDef.getCount() + 1;
                    String outpath = outputpath + File.separatorChar + resolveFileDef.getOutputFinalPath();

                    if("sql".equalsIgnoreCase(MyUtils.getExt(fileName)) ||
                            size == 0l){
                        continue;
                    }
                    else {
                        log(logWriter, defs.toString());
                        log(logWriter, "create filepath:" + outpath);

                        String[] _heads    = null;
                        JsonNode _headNode = null;

                        if("plaintxt".equalsIgnoreCase(converType)){
                            if(!StringUtils.isEmpty( resolveFileDef.getHeads() )){
                                _heads = MyUtils.getColArrays(resolveFileDef.getHeads(), resolveFileDef.getDefstr());
                            }
                            else{
                                _heads = MyUtils.getColArrays("v", colNum);
                            }
                        }
                        else if("json".equalsIgnoreCase(converType)){
                            log(logWriter, resolveFileDef.getDefstr() );
                            _headNode = objectMapper.readTree(resolveFileDef.getHeads());
                        }

                        String ddlStr = null;
                        if("plaintxt".equalsIgnoreCase(converType)){
                            ddlStr = generateTableDDL(tableName4ddl, _heads, headcountmakeupcount);
                        }
                        else if("json".equalsIgnoreCase(converType)){
                            ddlStr = generateTableDDLWithJson(tableName4ddl, _headNode);
                        }

                        FileUtils.forceMkdir( new File(outpath) );
                        // 生成对应的DDL 语句
                        String ddlFilePath = outpath + File.separatorChar +  tableName4ddl + "_ddl.sql";
                        File ddlFile = new File( ddlFilePath );
                        BufferedWriter ddlFileWriter = new BufferedWriter(new FileWriter(ddlFile));
                        ddlFileWriter.write( ddlStr );
                        if(ddlFileWriter != null) ddlFileWriter.close();
                    }
                }

            }
            // 3 根据预配置文件, 读取每个文件,并输出SQL
            else if("sql".equalsIgnoreCase(mode)){

                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, LinkedHashMap> o = objectMapper.readValue(new File(preconf), Map.class);
//                System.out.println(o);
                Set<String> keys = o.keySet();
                for(Map.Entry<String, LinkedHashMap> entry : o.entrySet()){
                    LinkedHashMap<String,Object> defs = entry.getValue();

                    String absPath = entry.getKey();
                    // System.out.println(entry.getValue());
                    ResolveFileDef resolveFileDef = convertMapToObject(defs,ResolveFileDef.class);
                    String tableName = resolveFileDef.getTableName();
                    String tableNameDDL = resolveFileDef.getTableName4ddl();
                    String fileName = resolveFileDef.getFileName();
                    long size = resolveFileDef.getSize();
                    int colNum       = resolveFileDef.getCount() + 1;

                    if(!StringUtils.isEmpty( resolveFileDef.getHeads() )){
                        String _t_defstr = resolveFileDef.getDefstr();
                        if("|".equals(_t_defstr)){
                            _t_defstr = "\\|";
                        }
                        colNum = resolveFileDef.getHeads().split(_t_defstr).length; //头部无需 +1
                        if(StringUtils.isNotEmpty(headcountmakeupcount)){
                            colNum = colNum + Integer.valueOf(headcountmakeupcount);
                        }
                    }

                    String delimiter = resolveFileDef.getDefstr();
                    String isNeedResolved = resolveFileDef.getIsNeedResolved();
                    if(!"1".equals(isNeedResolved))continue;

                    String outpath = outputpath + File.separatorChar + resolveFileDef.getOutputFinalPath();

                    if("sql".equalsIgnoreCase(MyUtils.getExt(fileName)) ||
                            size == 0l){
                        continue;
                    }
                    else {
                        long start = System.currentTimeMillis();
//                        String sqlStr = generateInsertStatements(tableName, MyUtils.getDataArrays());
////                        String ddlStr = generateInsertStatements(tableName, MyUtils.getColArrays("v", colNum + 1));
//                        FileUtils.forceMkdir( new File(outpath) );
//                        // 生成对应的DDL 语句
                        String sqlFilePath = outpath + File.separatorChar +  tableName + "_data.sql";
//                        File ddlFile = new File( ddlFilePath );
//                        BufferedWriter sqlFileWriter = new BufferedWriter(new FileWriter(ddlFile));
//                        sqlFileWriter.write( sqlStr );
//                        if(sqlFileWriter != null) sqlFileWriter.close();
                        log(logWriter,  absPath + "ready to generate data: " + outpath );
                        BufferedWriter writer = new BufferedWriter(new FileWriter(sqlFilePath));

                        int numcheck = 0;
                        BufferedReader reader = new BufferedReader(new FileReader( absPath ));

                        String line;
                        String lastLine = "";
                        // 逐行读取文件内容
                        while ((line = reader.readLine()) != null) {
                            if( numcheck ==0 &&
                                    !StringUtils.isEmpty( resolveFileDef.getHeads() ) ){ // 有head 跳过第一行
                                numcheck ++;
                                continue;
                            }

                            String _newline = null;
                            try{
                                if("plaintxt".equalsIgnoreCase(converType)){
                                    _newline = generateInsertStatements(tableNameDDL, MyUtils.getDataArrays(line, delimiter, colNum));
                                }
                                else if("json".equalsIgnoreCase(converType)){
                                    _newline = generateInsertStatementsWithJson(tableNameDDL, line);
                                }

                            }
                            catch (Exception e){
                                log(logWriter, e.getMessage());
                                continue;
                            }

                            if( StringUtils.isNotEmpty(_newline) ){
                                writer.write( _newline );
                                writer.newLine();
                                numcheck ++;
                                if((numcheck % 1000) == 0){
                                    writer.write( "commit;" );
                                    writer.newLine();
                                }
                            }
                            else{
                                log(logWriter, lastLine );
                            }

                            //记录上一行的数据
                            lastLine = line;
                        }
                        writer.write( "commit;" );
                        writer.newLine();
                        if(writer != null) writer.close();
                        long end = System.currentTimeMillis();
                        log(logWriter,  absPath + ", line checck num:" + numcheck + ",cost time:" + ((end-start)/1000) + "s" );

                    }
                }
            }

            if(logWriter != null) logWriter.close();

        }
        catch(Exception e){
            e.printStackTrace();
        }
        finally {

            if(logWriter!=null) {
                try {
                    logWriter.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        //            List<String[]> csvData = readCsv(csvFilePath);
        //            if (csvData != null && !csvData.isEmpty()) {
        //                String tableName = "your_table_name";
        //                generateTableDDL(tableName, csvData.get(0));
        //                generateInsertStatements(tableName, csvData);
        //            } else {
        //                System.out.println("CSV file is empty or could not be read.");
        //            }


        //        private static List<String[]> readCsv(String filePath) throws IOException {
        //        try (CSVReader csvReader = new CSVReaderBuilder(new FileReader(filePath)).build()) {
        //            return csvReader.readAll();
        //        } catch (CsvException e) {
        //            throw new RuntimeException(e);
        //        }
    }

    public static void log(BufferedWriter logwrter, String logstr) throws IOException {
        if(logwrter!=null){
            logwrter.write(logstr);
            logwrter.newLine();
        }
        if("print".equals(syslog)){
            System.out.println( logstr );
        }
    }

    private static String generateTableDDL(String tableName, String[] header, String headcountmakeupcount) {
        StringBuilder ddlStatement = new StringBuilder("CREATE TABLE ");
        ddlStatement.append(tableName).append(" (");

        for (String columnName : header) {
            //'\uFEFF' 65279
            columnName = columnName.replace("\uFEFF", ""); // vote数据里有奇怪的特殊字符需要作转换，不然DDL无法执行
            columnName = columnName.replace(" ", "_");
            columnName = columnName.replace("\\|", "");
            columnName = columnName.replace("(", "");
            columnName = columnName.replace(")", "");
            if (columnName.length() > 0 && Character.isDigit(columnName.charAt(0))) { // 字段名第一个字节不能是数字,如果是需要作一些补偿机制
                columnName = "v" + columnName;
            }
            // 特殊情况处理
            if(columnName.equalsIgnoreCase("_")){
                Random random = new Random();
                // 生成4位随机数
                int random4Digits = 1000000  + random.nextInt(9000000);
                columnName = "v" + random4Digits;
            }
//            else if( columnName.length() <= 2 ){
//                Random random = new Random();
//                // 生成4位随机数
//                int random4Digits = 1000000  + random.nextInt(9000000);
//                columnName = "v" + random4Digits;
//            }

            if(columnName.length() >= 31){
                columnName = columnName.substring(0, 30);
                System.out.println( columnName );
            }

            ddlStatement.append(columnName).append(" VARCHAR(1000), "); // Assuming all columns are strings
        }

        if(StringUtils.isNotEmpty(headcountmakeupcount)){ //不是空 说明需要从头部来作增加的控制，一般用于csv 字段设定操作
            int addCount = Integer.valueOf(headcountmakeupcount);
            for(int i = 1; i <= addCount; i++){
                ddlStatement.append("f" + i).append(" VARCHAR(1000), "); // Assuming all columns are strings
            }
        }
        // Remove the trailing comma and space
        ddlStatement.delete(ddlStatement.length() - 2, ddlStatement.length());
        ddlStatement.append(");");

        System.out.println("Table DDL Statement:");
        System.out.println(ddlStatement.toString());
        return ddlStatement.toString();
    }

    private static String generateTableDDLWithJson(String tableName, JsonNode jsonNode) {
        StringBuilder createTableSQL = new StringBuilder("CREATE TABLE "+ tableName +" (");

        jsonNode.fields().forEachRemaining(entry -> {
            String fieldName = entry.getKey();
            JsonNode fieldValue = entry.getValue();
            String fieldType = "VARCHAR(1000)";// 不做自动判断,强行写死 determineFieldType(fieldValue);
            if("type".equalsIgnoreCase(fieldName) ||
                    "date".equalsIgnoreCase(fieldName) ||
                    "size".equalsIgnoreCase(fieldName) ||
            "group".equalsIgnoreCase(fieldName)){ //关键字转义 for oracle
                fieldName = "\"" + fieldName.toUpperCase() + "\"";
            }
            createTableSQL.append(fieldName).append(" ").append(fieldType).append(", ");
        });

        // 删除最后一个逗号和空格
        createTableSQL.delete(createTableSQL.length() - 2, createTableSQL.length());
        createTableSQL.append(");");

        return createTableSQL.toString();
    }

    private static String determineFieldType(JsonNode fieldValue) {
        if (fieldValue.isTextual()) {
            return "VARCHAR(255)";
        } else if (fieldValue.isBoolean()) {
            return "BOOLEAN";
        } else if (fieldValue.isInt()) {
            return "INT";
        } else if (fieldValue.isLong()) {
            return "BIGINT";
        } else if (fieldValue.isDouble()) {
            return "DOUBLE";
        } else {
            return "VARCHAR(255)"; // Default to VARCHAR if type is uncertain
        }
    }


    private static String generateInsertStatements(String tableName, List<String> data) {
        if (data == null || data.isEmpty()) {
            System.out.println("CSV file is empty.");
            return "";
        }

        int numColumns = data.size();
        int num = 0;
        StringBuilder insertStatement = new StringBuilder("INSERT INTO ");
        insertStatement.append(tableName).append(" VALUES (");
        for (String col : data) {
            if(col.indexOf("'") != -1){
                col = col.replace("'", "''");
            }
            if(StringUtils.isNotEmpty(col)){
                col = col.trim();
            }
            // 特殊情况,处理 tip!!!!!!!!!!!!!!!!!!!!! 临时方案
            // col = col.replace(";",":");

            insertStatement.append("'").append(
                    MyUtils.makePlainWithoutQuote(col)
            ).append("', ");
            num ++;
            if( num == numColumns ){
                // Remove the trailing comma and space
                insertStatement.delete(insertStatement.length() - 2, insertStatement.length());
            }

        }
        insertStatement.append(");");
        return insertStatement.toString();
    }

    private static String generateInsertStatementsWithJson(String tableName, String data) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            JsonNode jsonNode = objectMapper.readTree(data);

            StringBuilder insertSQL = new StringBuilder("INSERT INTO " + tableName + " (");
            StringBuilder valuesSQL = new StringBuilder("VALUES (");

            jsonNode.fields().forEachRemaining(entry -> {
                String fieldName = entry.getKey();
                JsonNode fieldValue = entry.getValue();
                String _data = "";

                if("type".equalsIgnoreCase(fieldName) ||
                        "date".equalsIgnoreCase(fieldName) ||
                        "size".equalsIgnoreCase(fieldName) ||
                        "group".equalsIgnoreCase(fieldName)){ //关键字转义 for oracle
                    fieldName = "\"" + fieldName.toUpperCase() + "\"";
                }

                insertSQL.append(fieldName).append(", ");
                // 强行定义 varchar(1000) 无需判断字段类型
                if(fieldValue.asText().indexOf("'") != -1){
                    _data = fieldValue.asText().replace("'", "''");
                }
                else{
                    _data = fieldValue.asText();
                }
                valuesSQL.append("'").append(_data).append("', ");

                //                if (fieldValue.isTextual()) {
                //                    valuesSQL.append("'").append(fieldValue.asText()).append("', ");
                //                } else if (fieldValue.isBoolean()) {
                //                    valuesSQL.append(fieldValue.asBoolean()).append(", ");
                //                } else if (fieldValue.isInt()) {
                //                    valuesSQL.append(fieldValue.asInt()).append(", ");
                //                } else if (fieldValue.isLong()) {
                //                    valuesSQL.append(fieldValue.asLong()).append(", ");
                //                } else if (fieldValue.isDouble()) {
                //                    valuesSQL.append(fieldValue.asDouble()).append(", ");
                //                } else {
                //                    valuesSQL.append("NULL, "); // Default to NULL if type is uncertain
                //                }
            });

            // 删除最后一个逗号和空格
            insertSQL.delete(insertSQL.length() - 2, insertSQL.length());
            valuesSQL.delete(valuesSQL.length() - 2, valuesSQL.length());

            insertSQL.append(") ").append(valuesSQL).append(");");

            return insertSQL.toString();

        } catch (JsonProcessingException e) {
            System.out.println("CSV file is empty.");
            return "";
        }
    }

//    private static String generateInsertStatements(String tableName, List<String[]> data) {
//        if (data.isEmpty()) {
//            System.out.println("CSV file is empty.");
//            return "";
//        }
//
//        int numColumns = data.get(0).length;
//        StringBuilder insertStatement = new StringBuilder("INSERT INTO ");
//        for (String[] row : data) {
//            insertStatement.append(tableName).append(" VALUES (");
//
//            for (int i = 0; i < numColumns; i++) {
//                String value = i < row.length ? row[i] : "";
//                insertStatement.append("'").append(value).append("', ");
//            }
//
//            // Remove the trailing comma and space
//            insertStatement.delete(insertStatement.length() - 2, insertStatement.length());
//            insertStatement.append(");");
//
//            System.out.println("Insert Statement:");
//            System.out.println(insertStatement.toString());
//        }
//        return insertStatement.toString();
//    }


    private static <T> T convertMapToObject(Map<String, Object> map, Class<T> targetType) {
        try {
            T targetObject = targetType.getDeclaredConstructor().newInstance();

            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String fieldName = entry.getKey();
                Object value = entry.getValue();

                // Use reflection to set the field value
                java.lang.reflect.Field field = targetType.getDeclaredField(fieldName);
                field.setAccessible(true);
                field.set(targetObject, value);
            }

            return targetObject;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
